package com.knowledgegraph.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.knowledgegraph.entity.KnowledgeGraph;
import com.knowledgegraph.mapper.EntityMapper;
import com.knowledgegraph.mapper.KnowledgeGraphMapper;
import com.knowledgegraph.mapper.RelationMapper;
import com.knowledgegraph.service.KnowledgeGraphService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 知识图谱服务实现类
 * 
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@Service
public class KnowledgeGraphServiceImpl extends ServiceImpl<KnowledgeGraphMapper, KnowledgeGraph> 
        implements KnowledgeGraphService {

    @Autowired
    private KnowledgeGraphMapper knowledgeGraphMapper;

    @Autowired
    private EntityMapper entityMapper;

    @Autowired
    private RelationMapper relationMapper;

    @Override
    public boolean createGraph(KnowledgeGraph knowledgeGraph, Long creatorId) {
        knowledgeGraph.setCreatorId(creatorId);
        knowledgeGraph.setLastEditorId(creatorId);
        knowledgeGraph.setEntityCount(0);
        knowledgeGraph.setRelationCount(0);
        knowledgeGraph.setProgress(0);
        
        if (knowledgeGraph.getStatus() == null) {
            knowledgeGraph.setStatus(0); // 默认草稿状态
        }
        if (knowledgeGraph.getIsPublic() == null) {
            knowledgeGraph.setIsPublic(0); // 默认私有
        }
        
        return save(knowledgeGraph);
    }

    @Override
    public boolean updateGraph(KnowledgeGraph knowledgeGraph, Long userId) {
        KnowledgeGraph existingGraph = getById(knowledgeGraph.getId());
        if (existingGraph == null) {
            throw new RuntimeException("知识图谱不存在");
        }
        
        // 检查权限
        if (!hasGraphPermission(knowledgeGraph.getId(), userId)) {
            throw new RuntimeException("没有权限修改此知识图谱");
        }
        
        knowledgeGraph.setLastEditorId(userId);
        return updateById(knowledgeGraph);
    }

    @Override
    public boolean deleteGraph(Long graphId, Long userId) {
        KnowledgeGraph graph = getById(graphId);
        if (graph == null) {
            throw new RuntimeException("知识图谱不存在");
        }
        
        // 检查权限
        if (!hasGraphPermission(graphId, userId)) {
            throw new RuntimeException("没有权限删除此知识图谱");
        }
        
        return removeById(graphId);
    }

    @Override
    public List<KnowledgeGraph> getGraphsByCreator(Long creatorId) {
        return knowledgeGraphMapper.findByCreatorId(creatorId);
    }

    @Override
    public IPage<KnowledgeGraph> getPublicGraphs(Page<KnowledgeGraph> page) {
        return knowledgeGraphMapper.findPublicGraphs(page);
    }

    @Override
    public IPage<KnowledgeGraph> searchGraphs(String keyword, Page<KnowledgeGraph> page) {
        QueryWrapper<KnowledgeGraph> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> {
            if (StringUtils.hasText(keyword)) {
                wrapper.like("name", keyword)
                       .or()
                       .like("description", keyword)
                       .or()
                       .like("category", keyword);
            }
        });
        queryWrapper.eq("deleted", 0);
        queryWrapper.orderByDesc("update_time");
        
        return page(page, queryWrapper);
    }

    @Override
    public Map<String, Object> getGraphStatistics(Long userId) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 用户创建的图谱数量
        Integer userGraphCount = knowledgeGraphMapper.countByCreatorId(userId);
        statistics.put("userGraphCount", userGraphCount);
        
        // 总图谱数量
        QueryWrapper<KnowledgeGraph> totalWrapper = new QueryWrapper<>();
        totalWrapper.eq("deleted", 0);
        Integer totalGraphCount = Math.toIntExact(count(totalWrapper));
        statistics.put("totalGraphCount", totalGraphCount);
        
        // 公开图谱数量
        QueryWrapper<KnowledgeGraph> publicWrapper = new QueryWrapper<>();
        publicWrapper.eq("is_public", 1).eq("deleted", 0);
        Integer publicGraphCount = Math.toIntExact(count(publicWrapper));
        statistics.put("publicGraphCount", publicGraphCount);
        
        // 用户图谱的总实体数和关系数
        List<KnowledgeGraph> userGraphs = getGraphsByCreator(userId);
        int totalEntities = userGraphs.stream().mapToInt(g -> g.getEntityCount() != null ? g.getEntityCount() : 0).sum();
        int totalRelations = userGraphs.stream().mapToInt(g -> g.getRelationCount() != null ? g.getRelationCount() : 0).sum();
        
        statistics.put("totalEntities", totalEntities);
        statistics.put("totalRelations", totalRelations);
        
        return statistics;
    }

    @Override
    public void updateGraphStatistics(Long graphId) {
        // 统计实体数量
        Integer entityCount = entityMapper.countByGraphId(graphId);
        
        // 统计关系数量
        Integer relationCount = relationMapper.countByGraphId(graphId);
        
        // 更新图谱统计信息
        KnowledgeGraph graph = new KnowledgeGraph();
        graph.setId(graphId);
        graph.setEntityCount(entityCount);
        graph.setRelationCount(relationCount);
        
        // 计算完成度（简单算法：实体数 + 关系数 > 10 为基础完成度50%）
        int progress = Math.min(90, 50 + (entityCount + relationCount) * 2);
        graph.setProgress(progress);
        
        updateById(graph);
    }

    @Override
    public boolean hasGraphPermission(Long graphId, Long userId) {
        KnowledgeGraph graph = getById(graphId);
        if (graph == null) {
            return false;
        }
        
        // 创建者有权限
        if (graph.getCreatorId().equals(userId)) {
            return true;
        }
        
        // 公开图谱所有人都可以查看
        if (graph.getIsPublic() == 1) {
            return true;
        }
        
        // TODO: 可以扩展协作者权限
        
        return false;
    }
}